package com.apes.oap.event;

import java.util.*;

public abstract class AbstractRopEventMulticaster implements RopEventMulticaster {

    private Set<RopEventListener> ropEventListeners = new HashSet<RopEventListener>();

    private static final Map<Class<? extends OapEvent>, List> cachedRopEventListeners = new HashMap<>();

    public void removeAllRopListeners() {
        ropEventListeners.clear();
    }

    public void addRopListener(RopEventListener listener) {
        ropEventListeners.add(listener);
        cacheListener(listener);
    }

    public void removeRopListener(RopEventListener listener) {
        ropEventListeners.remove(listener);
    }

    protected List<RopEventListener> getRopEventListeners(OapEvent event) {
        Class<? extends OapEvent> eventType = event.getClass();
        return cachedRopEventListeners.get(eventType);
    }

    private void cacheListener(RopEventListener listener) {
        SmartRopEventListener smartListener = (listener instanceof SmartRopEventListener ? (SmartRopEventListener) listener : new GenericRopEventAdapter(listener));
        Class eventType = smartListener.getEventType();
        List<RopEventListener> listeners = cachedRopEventListeners.get(eventType);
        if (listeners == null) {
            listeners = new LinkedList<>();
            cachedRopEventListeners.put(eventType, listeners);
        }
        if (!listeners.contains(listener)) {
            listeners.add(listener);
        }
        sortRopEventListener(listeners);
    }

    protected void sortRopEventListener(List<RopEventListener> ropEventListeners) {
        Collections.sort(ropEventListeners, (o1, o2) -> {
            if (o1.getOrder() > o2.getOrder()) {
                return 1;
            } else if (o1.getOrder() < o2.getOrder()) {
                return -1;
            } else {
                return 0;
            }
        });
    }
}
